#include <MQTTClient.h>
#include "log/log.h"
#include "app_mqtt.h"
#include <string.h>

static MQTTClient client;
static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
static MQTTClient_message pubmsg = MQTTClient_message_initializer;

static int (*recv_callback)(char *json) = NULL;

// 发送消息完成的回调函数
static void delivered(void *context, MQTTClient_deliveryToken dt)
{
    log_debug("发送消息完成");
}

// 接收到消息的回调函数
// 返回标识是否成功处理消息的结果值，1：成功，0：失败
static int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int result = 0; // 0: 失败，1：成功

    if (recv_callback != NULL) {
        result = recv_callback(message->payload) == 0 ? 1 : 0;
    }

    // 释放内存
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);

    return result;
}

// 连接断开时的回调函数
static void connlost(void *context, char *cause)
{
    log_error("连接断开, 原因: %s", cause);
}

int app_mqtt_init() {

    // 1. 创建mqtt客户端
    if (MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL) != MQTTCLIENT_SUCCESS) {
        log_error("创建mqtt客户端失败");
        return -1;
    }
    // 2. 设置回调
    if (MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered) != MQTTCLIENT_SUCCESS) {
        log_error("设置mqtt回调失败");
        MQTTClient_destroy(&client);
        return -1;
    }

    // 3. 连接mqtt服务器
    if (MQTTClient_connect(client, &conn_opts) != MQTTCLIENT_SUCCESS) {
        log_error("连接mqtt服务器失败");
        MQTTClient_destroy(&client);
        return -1;
    }

    // 4. 订阅主题
    if (MQTTClient_subscribe(client, TOPIC_PULL, QOS) != MQTTCLIENT_SUCCESS) {
        log_error("订阅主题失败");
        MQTTClient_disconnect(client, TIMEOUT);
        MQTTClient_destroy(&client);
        return -1;
    }
    log_debug("MQTT模块初始化成功");
    
    return 0;
}

void app_mqtt_close() {
    MQTTClient_unsubscribe(client, TOPIC_PULL);
    MQTTClient_disconnect(client, TIMEOUT);
    MQTTClient_destroy(&client);
}


int app_mqtt_send(char *json) {

    // 给pubmsg指定数据和数据长度
    pubmsg.payload = json;
    pubmsg.payloadlen = strlen(json);

    if (MQTTClient_publishMessage(client, TOPIC_PUSH, &pubmsg, NULL) != MQTTCLIENT_SUCCESS) {
        log_error("发送消息失败");
        return -1;
    }
    log_debug("发送消息成功: %s", json);

    return 0;
}

void app_mqtt_registerRecvCallback(int (*callback)(char *json)) {
    recv_callback = callback;
}